package com.dodayum.service;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.TopHits;
import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder;
import org.elasticsearch.search.aggregations.pipeline.BucketSortPipelineAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class Back {


    private final RestHighLevelClient client;

    public Back(RestHighLevelClient client) {
        this.client = client;
    }

    public RestHighLevelClient getClient() {
        return client;
    }

    /**
     * 构建查询请求
     */
    private SearchRequest buildSearchRequest(String indexName, int from, int size) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();


        // query
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.filter(QueryBuilders.termsQuery("assetHealthState", new ArrayList<>(Arrays.asList("high_risk", "low_risk", "fallen"))));
        // 设置查询条件（如果有）
        sourceBuilder.query(boolQueryBuilder);
        // 设置返回结果为聚合结果
        sourceBuilder.size(0);


        String appName = "group_by_assetId_and_healthState";
        String appTopHistName = "latest_ratingTime";

        // 构建 terms 聚合，基于 script
        TermsAggregationBuilder termsAggregation = AggregationBuilders.terms(appName)
                .script(new Script("doc['assetId'].value + '|' + doc['assetHealthState'].value"))
                .size(Integer.MAX_VALUE);

        FetchSourceContext fetchSourceContext = new FetchSourceContext(true, new String[]{"assetScore", "updateTime", "rateGroup", "ratingTime", "tags", "relationContent",
                "warehouseTime", "createTime", "assetId", "assetHealthState", "alarmTop",
                "fromSubordinatePlatform", "id"}, null);

        // 添加 top_hits 子聚合
        TopHitsAggregationBuilder topHitsAggregation = AggregationBuilders.topHits(appTopHistName)
                .from(0)
                .size(1)
                .fetchSource(fetchSourceContext)
                .sort("ratingTime", SortOrder.DESC);

        termsAggregation.subAggregation(topHitsAggregation);

        // 分页
        BucketSortPipelineAggregationBuilder bucketSortAggregation = new BucketSortPipelineAggregationBuilder(
                "pagination",
                Collections.singletonList(
                        new FieldSortBuilder("_key").order(SortOrder.ASC)
                )
        );
        bucketSortAggregation.from(from); // 设置起始位置
        bucketSortAggregation.size(size); // 设置每页大小
        termsAggregation.subAggregation(bucketSortAggregation);

        // 将聚合添加到查询中
        sourceBuilder.aggregation(termsAggregation);

        // 创建 SearchRequest
        SearchRequest searchRequest = new SearchRequest(indexName);
        searchRequest.source(sourceBuilder);

        return searchRequest;
    }

    public static void main(String[] args) throws IOException {

        // 初始化查询类
        DemoService queryExample = new DemoService(null);

        // 构建json命令
        SearchRequest demo = queryExample.buildSearchRequest("ailpha-mirror-asset", 1, 10);
        System.out.println(demo.source());

        // 开始查询
        RestHighLevelClient client = queryExample.getClient();
        SearchResponse search = client.search(demo, RequestOptions.DEFAULT);
        // 获取值
        Aggregation aggregation = search.getAggregations().get("group_by_assetId_and_healthState");
        Terms terms = (Terms) aggregation;
        for (Terms.Bucket bucket : terms.getBuckets()) {
            String keyAsString = bucket.getKeyAsString();
            long docCount = bucket.getDocCount();

            System.out.println("key:" + keyAsString);
            System.out.println("count:" + docCount);
            TopHits topHits = bucket.getAggregations().get("latest_ratingTime");
            if (!ObjectUtils.isEmpty(topHits)) {
                for (SearchHit hit : topHits.getHits()) {
                    String sourceAsString = hit.getSourceAsString();
                    // 最终获取值
                    System.out.println(sourceAsString); // 这里是个string字符串
                }
            }
        }

    }
}
